package com.example.supernote.ui.manager

import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Article
import androidx.compose.material.icons.filled.AutoAwesome
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.EditNote
import androidx.compose.material.icons.filled.Folder
import androidx.compose.material.icons.filled.FolderOpen
import androidx.compose.material.icons.filled.HourglassEmpty
import androidx.compose.material.icons.filled.ImportExport
import androidx.compose.material.icons.filled.OpenWith
import androidx.compose.material.icons.filled.SortByAlpha
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.example.supernote.R
import com.example.supernote.model.manager.AbstractFileComposite
import com.example.supernote.model.manager.FileType
import com.example.supernote.ui.components.UniformButton
import com.example.supernote.ui.components.UniformIcon
import com.example.supernote.ui.trash.ConfirmDialog
import com.example.supernote.ui.trash.PromptDialog
import com.example.supernote.ui.utils.getSystemPrompt
import com.example.supernote.utils.dateToFormatString


@Composable
fun ManagerContent(
    uiState: ManagerUiState,
    deleteFile: (AbstractFileComposite) -> Unit,
    sortFile: () -> Unit,
    editFile: (AbstractFileComposite) -> Unit,
    exportFile: (AbstractFileComposite) -> Unit,
    forward: (AbstractFileComposite) -> Unit,
    backward: () -> Unit,
    preClassified: (List<AbstractFileComposite>, systemPrompt: String, update: (Map<String, ArrayList<AbstractFileComposite>>) -> Unit) -> Unit,
    autoClassified: () -> Unit,
    moveFilePath: (path: String, file: AbstractFileComposite) -> Unit,
    modifier: Modifier = Modifier
) {
    val composite = uiState.itemDisplay
    val isSorted = uiState.isSorted
    val searchPattern = uiState.searchPattern
    var children = composite.children.filter {
        try {
            if (searchPattern != "")
                it.property!!.name.contains(Regex(searchPattern))
            else
                true
        } catch (e: Exception) {
            it.property!!.name.contains(searchPattern, ignoreCase = true)
        }
    }
    val unClassified = composite.children.filter {
        it.property!!.type == FileType.FILE
    }
    if (isSorted) {
        children = ArrayList(composite.children.sortedBy { it.property!!.name })
    }
    Column(modifier = modifier) {
        HorizontalDivider(modifier = Modifier)
        val barModifier = Modifier.padding(5.dp)
        when (composite.property!!.type) {
            FileType.ROOT -> RootFolderBar(
                modifier = barModifier,
                composite = composite,
                unClassified = unClassified,
                preClassified = preClassified,
                autoClassified = autoClassified,
                moveFilePath = moveFilePath,
                sortFile = sortFile
            )

            FileType.FOLDER -> NormalFolderBar(
                modifier = barModifier,
                composite = composite,
                sortFile = sortFile,
                deleteFile = deleteFile,
                backward = backward
            )

            FileType.FILE -> TODO()
        }
        HorizontalDivider(modifier = Modifier)
        val itemModifier = Modifier
            .padding(5.dp)
            .heightIn(min = 32.dp)
        if (children.isNotEmpty()) {
            LazyColumn {
                items(children) { child ->
                    when (child.property!!.type) {
                        FileType.ROOT, FileType.FOLDER -> FolderDisplay(
                            folder = child,
                            onClick = {
                                forward(child)
                            },
                            modifier = itemModifier
                        )

                        FileType.FILE -> FileDisplay(
                            file = child,
                            editFile = editFile,
                            exportFile = exportFile,
                            deleteFile = deleteFile,
                            moveFilePath = moveFilePath,
                            modifier = itemModifier
                        )
                    }
                }
            }
        } else {
            EmptyDisplay(modifier = Modifier.fillMaxSize())
        }
    }
}

@Composable
fun FolderDisplay(
    folder: AbstractFileComposite,
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
) {
    Column(
        modifier = modifier
            .fillMaxWidth()
            .clickable(onClick = onClick)
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            UniformIcon(imageVector = Icons.Filled.Folder)
            Text(
                text = folder.property!!.name,
                modifier = Modifier
                    .fillMaxWidth()
                    .horizontalScroll(
                        rememberScrollState()
                    )
            )
        }
        Row(
            modifier = Modifier
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.End,
        ) {
            Text(
                text = dateToFormatString(folder.property!!.lastModified)
            )
        }
    }
}

@Composable
fun FileDisplay(
    file: AbstractFileComposite,
    editFile: (AbstractFileComposite) -> Unit,
    exportFile: (AbstractFileComposite) -> Unit,
    deleteFile: (AbstractFileComposite) -> Unit,
    moveFilePath: (path: String, file: AbstractFileComposite) -> Unit,
    modifier: Modifier = Modifier,
) {
    var isExpand: Boolean by remember {
        mutableStateOf(false)
    }
    Column(
        modifier = modifier.clickable(onClick = {
            isExpand = !isExpand
        })
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .height(32.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            UniformIcon(imageVector = Icons.Filled.Article)
            Text(
                text = file.property!!.name,
                modifier = Modifier
                    .fillMaxWidth()
                    .horizontalScroll(
                        rememberScrollState()
                    )
            )
        }
        Row(
            modifier = Modifier
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.End,
        ) {
            Text(
                text = dateToFormatString(file.property!!.lastModified)
            )
        }
        if (isExpand) {
            FileExpandDisplay(
                file = file,
                editFile = editFile,
                exportFile = exportFile,
                deleteFile = deleteFile,
                moveFilePath = moveFilePath
            )
        }
    }
}

@Composable
fun FileExpandDisplay(
    file: AbstractFileComposite,
    editFile: (AbstractFileComposite) -> Unit,
    exportFile: (AbstractFileComposite) -> Unit,
    deleteFile: (AbstractFileComposite) -> Unit,
    moveFilePath: (path: String, file: AbstractFileComposite) -> Unit,
) {
    var isVisible by remember {
        mutableStateOf(false)
    }
    var moveFileVisible by remember {
        mutableStateOf(false)
    }
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {
        UniformButton(
            onClick = {
                moveFileVisible = true
            },
            imageVector = Icons.Filled.OpenWith,
            text = stringResource(id = R.string.manager_move)
        )
        Spacer(modifier = Modifier.width(5.dp))
        UniformButton(
            onClick = {
                editFile(file)
            },
            imageVector = Icons.Filled.EditNote,
            text = stringResource(id = R.string.manager_edit)
        )
        Spacer(modifier = Modifier.width(5.dp))
        UniformButton(
            onClick = {
                exportFile(file)
            },
            imageVector = Icons.Filled.ImportExport,
            text = stringResource(id = R.string.manager_export)
        )
        Spacer(modifier = Modifier.width(5.dp))
        UniformButton(
            onClick = {
                isVisible = true
            },
            imageVector = Icons.Filled.Delete,
            text = stringResource(id = R.string.manager_delete)
        )
//        Spacer(modifier = Modifier.width(5.dp))
//        UniformButton(
//            onClick = {
//            },
//            imageVector = Icons.Filled.ArrowBack,
//            text = "闹钟"
//        )
    }
    if (isVisible) {
        ConfirmDialog(
            confirmTitle = stringResource(id = R.string.manager_deleteConfirm_file),
            onConfirm = { deleteFile(file) },
            onCancel = {
                isVisible = false
            })
    }
    if (moveFileVisible) {
        MoveFile(
            file = file,
            onConfirm = { path -> moveFilePath(path, file) },
            onCancel = { moveFileVisible = false },
            originVisible = {})
    }
}

@Composable
fun EmptyDisplay(modifier: Modifier = Modifier) {
    Row(
        modifier = Modifier
            .padding(10.dp)
            .fillMaxWidth(),
    ) {
        UniformIcon(imageVector = Icons.Filled.HourglassEmpty)
        Spacer(modifier = Modifier.width(5.dp))
        Text(text = stringResource(id = R.string.manager_empty), color = Color.Gray)
    }
}

@Composable
fun FolderNameDisplay(name: String) {
    UniformIcon(imageVector = Icons.Filled.FolderOpen)
    Spacer(modifier = Modifier.width(5.dp))
    Text(
        text = if (name == ".") name else ".. / $name",
        modifier = Modifier
            .widthIn(max = 120.dp)
            .horizontalScroll(
                rememberScrollState()
            ),
        fontWeight = FontWeight.Bold
    )
}

@Composable
fun RootFolderBar(
    modifier: Modifier,
    composite: AbstractFileComposite,
    unClassified: List<AbstractFileComposite>,
    preClassified: (List<AbstractFileComposite>, systemPrompt: String, update: (Map<String, ArrayList<AbstractFileComposite>>) -> Unit) -> Unit,
    autoClassified: () -> Unit,
    moveFilePath: (path: String, file: AbstractFileComposite) -> Unit,
    sortFile: () -> Unit
) {
    var isVisible by remember {
        mutableStateOf(false)
    }
    var isAutoClassified by remember {
        mutableStateOf(false)
    }
    var preClassifiedList: Map<String, ArrayList<AbstractFileComposite>> by remember {
        mutableMapOf()
    }
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {
        FolderNameDisplay(composite.property!!.name)
        Spacer(modifier = Modifier.weight(1f))
        val systemPrompt = getSystemPrompt(stringResource(R.string.manager_auto_classified))
        UniformButton(
            onClick = {
                preClassifiedList = mapOf()
                if (unClassified.isNotEmpty()) {
                    isAutoClassified = true
                    preClassified(unClassified, systemPrompt) {
                        preClassifiedList = it
                        isVisible = true
                        isAutoClassified = false
                    }
                } else {
                    isAutoClassified = true
                    isVisible = true
                    isAutoClassified = false
                }
            },
            enabled = !isAutoClassified,
            imageVector = Icons.Filled.AutoAwesome,
            text = if (isAutoClassified) stringResource(id = R.string.manager_classifying) else stringResource(id = R.string.manager_auto_classified)
        )
        Spacer(modifier = Modifier.width(5.dp))
        UniformButton(
            onClick = {
                sortFile()
            },
            imageVector = Icons.Filled.SortByAlpha,
            text = stringResource(id = R.string.manager_sort)
        )
    }
    if (isVisible) {
        if (unClassified.isEmpty()) {
            PromptDialog(confirmTitle = stringResource(id = R.string.manager_already_classified), onCancel = {
                isVisible = false
            })
        } else {
            PreClassified(
                onConfirm = { autoClassified() },
                onCancel = { isVisible = false },
                preClassifiedList = preClassifiedList,
                moveFilePath = moveFilePath,
                originVisible = { isVisible = false }
            )
        }
    }
}

@Composable
fun NormalFolderBar(
    modifier: Modifier,
    composite: AbstractFileComposite,
    sortFile: () -> Unit,
    deleteFile: (AbstractFileComposite) -> Unit,
    backward: () -> Unit
) {
    var isVisible by remember {
        mutableStateOf(false)
    }
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically
    ) {
        UniformButton(
            onClick = {
                backward()
            },
            imageVector = Icons.Filled.ArrowBack,
            text = stringResource(id = R.string.manager_back)
        )
        Spacer(modifier = Modifier.width(5.dp))
        FolderNameDisplay(composite.property!!.name)
        Spacer(modifier = Modifier.weight(1f))
        UniformButton(
            onClick = {
                isVisible = true
            },
            imageVector = Icons.Filled.Delete,
            text = stringResource(id = R.string.manager_delete)
        )
        Spacer(modifier = Modifier.width(5.dp))
        UniformButton(
            onClick = {
                sortFile()
            },
            imageVector = Icons.Filled.SortByAlpha,
            text = stringResource(id = R.string.manager_sort)
        )
    }
    if (isVisible) {
        ConfirmDialog(
            confirmTitle = stringResource(id = R.string.manager_deleteConfirm_folder),
            onConfirm = { deleteFile(composite) },
            onCancel = {
                isVisible = false
            })
    }
}